//
//  TimerUtils.swift
//
//  Created by Ink on 2024-03-15.
//

import Foundation

public class Block<T> {
    let f : T
    init(_ f: T) { self.f = f }
}

public extension Timer {
    class func compatibleScheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping (Timer) -> Swift.Void) -> Timer {
        if #available(iOS 10.0, *) {
            return Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats, block: block)
        }
        return Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(timerAction), userInfo: Block(block), repeats: repeats)
    }
    
    @objc private class func timerAction(_ sender: Timer) {
        if let block = sender.userInfo as? Block<(Timer) -> Swift.Void> {
            block.f(sender)
        }
    }
}

public typealias ActionBlock = () -> ()

open class MCGCDTimer {
    //单例
    public static let shared = MCGCDTimer()
    
    public lazy var timerContainer = [String: DispatchSourceTimer]()
    
}

public extension MCGCDTimer {
    /// GCD定时器
    ///
    /// - Parameters:
    ///   - name: 定时器名字
    ///   - timeInterval: 时间间隔
    ///   - queue: 队列
    ///   - repeats: 是否重复
    ///   - action: 执行任务的闭包
    func scheduledDispatchTimer(WithTimerName name: String?, timeInterval: Double, queue: DispatchQueue = .main, repeats: Bool, action: @escaping ActionBlock) {
        
        cancleTimer(WithTimerName: name)

        guard let name = name else { return }
        var timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
        timerContainer[name] = timer
        
        //精度0.1秒
        timer.schedule(deadline: .now(), repeating: timeInterval, leeway: DispatchTimeInterval.milliseconds(100))
        timer.setEventHandler(handler: { [weak self] in
            action()
            if repeats == false {
                self?.cancleTimer(WithTimerName: name)
            }
        })
        timer.resume()
    }
    
    /// 取消定时器
    ///
    /// - Parameter name: 定时器名字
    func cancleTimer(WithTimerName name: String?) {
        guard let name = name else { return }
        timerContainer[name]?.cancel()
        timerContainer.removeValue(forKey: name)
    }
    
    
    /// 检查定时器是否已存在
    ///
    /// - Parameter name: 定时器名字
    /// - Returns: 是否已经存在定时器
    func isExistTimer(WithTimerName name: String?) -> Bool {
        timerContainer[name] != nil
    }
    
    func timer(_ name: String?) -> DispatchSourceTimer? {
        timerContainer[name]
    }
}


